package com.yunhe.abnormal.service.base.impl;

import com.yunhe.common.constant.CacheConsts;
import com.yunhe.abnormal.domain.base.AbnormalStatus;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.abnormal.mapper.base.AbnormalStatusMapper;
import com.yunhe.common.model.base.AbnormalStatusDTO;
import com.yunhe.abnormal.repository.base.AbnormalStatusRepository;
import com.yunhe.abnormal.service.base.AbnormalStatusService;
import com.yunhe.abnormal.transaction.MultiTransaction;
import com.yunhe.common.util.QueryUtil;
import com.yunhe.common.util.StringUtil;
import net.oschina.j2cache.cache.support.util.SpringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class AbnormalStatusServiceImpl implements AbnormalStatusService {

    @Autowired
    private AbnormalStatusRepository abnormalTypeRepository;
    @Autowired
    private AbnormalStatusMapper abnormalStatusMapper;

    /**
     * 异常处理状态对象处理和判断
     * @param AbnormalStatus 异常处理状态对象
     */
    private void processBeforeSave(AbnormalStatus AbnormalStatus)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        //判断异常处理状态代码、编号、标题是否为空
        if (AbnormalStatus.getCode() == null
                || StringUtil.isEmpty(AbnormalStatus.getName())
                || StringUtil.isEmpty(AbnormalStatus.getTitle())) {
            throw new ArgumentErrorException("异常处理状态代码、编号、标题不能为空");
        }
        //判断代码是否已存在
        AbnormalStatusDTO typeByCode = SpringUtil.getBean(AbnormalStatusService.class).findByCode(AbnormalStatus.getCode());
        if (typeByCode != null) {
            if (AbnormalStatus.getId() == null || typeByCode.getId().longValue() != AbnormalStatus.getId().longValue()) {
                throw new UniqueConstraintsException("该异常处理状态代码已存在");
            }
        }
        //判断编号是否已存在
        AbnormalStatusDTO typeByName = SpringUtil.getBean(AbnormalStatusService.class).findByName(AbnormalStatus.getName());
        if (typeByName != null) {
            if (AbnormalStatus.getId() == null || typeByName.getId().longValue() != AbnormalStatus.getId().longValue()) {
                throw new UniqueConstraintsException("该异常处理状态编号已存在");
            }
        }
        //如果序号为空，则默认为代码
        if (AbnormalStatus.getSn() != null && AbnormalStatus.getCode() != null) {
            AbnormalStatus.setSn(AbnormalStatus.getCode());
        }
    }

    /**
     * 新增异常处理状态
     * @param AbnormalStatus 异常处理状态对象
     */
    @Override
    @MultiTransaction
    @CacheEvict(value = CacheConsts.Region.ABNORMAL_STATUS, allEntries = true)
    public AbnormalStatusDTO createAbnormalStatus(AbnormalStatus AbnormalStatus)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        AbnormalStatus.setId(null);
        processBeforeSave(AbnormalStatus);
        AbnormalStatus result = abnormalTypeRepository.save(AbnormalStatus);
        return abnormalStatusMapper.to(result);
    }

    /**
     * 批量新增异常处理状态
     * @param AbnormalStatusList 异常处理状态对象列表
     */
    @Override
    @MultiTransaction
    @CacheEvict(value = CacheConsts.Region.ABNORMAL_STATUS, allEntries = true)
    public Iterable<AbnormalStatusDTO> createAbnormalStatus(List<AbnormalStatus> AbnormalStatusList)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        List<AbnormalStatusDTO> newAbnormalStatusList = new ArrayList<>();
        for (AbnormalStatus abnormalStatus : AbnormalStatusList) {
            AbnormalStatusDTO abnormalStatusDTO = createAbnormalStatus(abnormalStatus);
            newAbnormalStatusList.add(abnormalStatusDTO);
        }
        return newAbnormalStatusList;
    }

    /**
     * 删除异常处理状态
     * @param id 异常处理状态ID
     */
    @Override
    @MultiTransaction
    @CacheEvict(value = CacheConsts.Region.ABNORMAL_STATUS, allEntries = true)
    public void deleteAbnormalStatus(Long id) {
        abnormalTypeRepository.deleteById(id);
    }

    /**
     * 更新异常处理状态（更新全部字段）
     * @param AbnormalStatus 异常处理状态对象
     */
    @Override
    @MultiTransaction
    @CacheEvict(value = CacheConsts.Region.ABNORMAL_STATUS, allEntries = true)
    public AbnormalStatusDTO updateAbnormalStatus(AbnormalStatus AbnormalStatus)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        boolean exists = AbnormalStatus.getId() != null && abnormalTypeRepository.existsById(AbnormalStatus.getId());
        if (!exists) {
            throw new ObjectNotFoundException("找不到ID为" + AbnormalStatus.getId() + "的异常处理状态");
        }
        processBeforeSave(AbnormalStatus);
        AbnormalStatus result = abnormalTypeRepository.save(AbnormalStatus);
        return abnormalStatusMapper.to(result);
    }

    /**
     * 更新异常处理状态（更新指定字段）
     * @param id 异常处理状态ID
     * @param code 代码
     * @param name 编号
     * @param title 标题
     * @param sn 排序序号
     * @param activity 是否可用
     */
    @Override
    @MultiTransaction
    @CacheEvict(value = CacheConsts.Region.ABNORMAL_STATUS, allEntries = true)
    public AbnormalStatusDTO updateAbnormalStatus(Long id,
                                                  Optional<Long> code,
                                                  Optional<String> name,
                                                  Optional<String> title,
                                                  Optional<Long> sn,
                                                  Optional<Boolean> activity)
            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException {
        AbnormalStatus abnormalStatus = abnormalTypeRepository.findById(id).orElse(null);
        if (abnormalStatus == null) {
            throw new ObjectNotFoundException("找不到ID为" + id + "的异常处理状态");
        }
        code.ifPresent(abnormalStatus::setCode);
        name.ifPresent(abnormalStatus::setName);
        title.ifPresent(abnormalStatus::setTitle);
        sn.ifPresent(abnormalStatus::setSn);
        activity.ifPresent(abnormalStatus::setActivity);
        processBeforeSave(abnormalStatus);
        AbnormalStatus result = abnormalTypeRepository.save(abnormalStatus);
        return abnormalStatusMapper.to(result);
    }

    /**
     * 根据ID获得异常处理状态对象
     * @param id 状态ID
     */
    @Override
    @Cacheable(value = CacheConsts.Region.ABNORMAL_STATUS,
            key = "{T(com.yunhe.abnormal.consts.AbnormalStatusKey).getIdKey(#id, T(com.yunhe.common.i18n.LanguageHolder).LANGUAGE_HOLDER.get())}")
    public AbnormalStatusDTO findById(Long id) {
        AbnormalStatus abnormalStatus =  abnormalTypeRepository.findById(id).orElse(null);
        return abnormalStatusMapper.to(abnormalStatus);
    }

    /**
     * 根据代码获得异常处理状态对象
     * @param code 代码
     */
    @Override
    @Cacheable(value = CacheConsts.Region.ABNORMAL_STATUS,
            key = "{T(com.yunhe.abnormal.consts.AbnormalStatusKey).getCodeKey(#code, T(com.yunhe.common.i18n.LanguageHolder).LANGUAGE_HOLDER.get())}")
    public AbnormalStatusDTO findByCode(Long code) {
        AbnormalStatus abnormalStatus =  abnormalTypeRepository.findByCode(code);
        return abnormalStatusMapper.to(abnormalStatus);
    }

    /**
     * 根据编号获得异常处理状态对象
     * @param name 编号
     */
    @Override
    @Cacheable(value = CacheConsts.Region.ABNORMAL_STATUS,
            key = "{T(com.yunhe.abnormal.consts.AbnormalStatusKey).getNameKey(#name, T(com.yunhe.common.i18n.LanguageHolder).LANGUAGE_HOLDER.get())}")
    public AbnormalStatusDTO findByName(String name) {
        AbnormalStatus abnormalStatus = abnormalTypeRepository.findByName(name);
        return abnormalStatusMapper.to(abnormalStatus);
    }

    /**
     * 获得全部异常处理状态对象
     */
    @Override
    @Cacheable(value = CacheConsts.Region.ABNORMAL_STATUS,
            key = "{T(com.yunhe.abnormal.consts.AbnormalStatusKey).getAllKey(T(com.yunhe.common.i18n.LanguageHolder).LANGUAGE_HOLDER.get())}")
    public Iterable<AbnormalStatusDTO> findAll() {
        List<AbnormalStatus> abnormalStatuses = (List<AbnormalStatus>) abnormalTypeRepository.findAll(QueryUtil.defaultSort());
        return abnormalStatusMapper.to(abnormalStatuses);
    }

    @Override
    @MultiTransaction
    public void bindAlarmStatus(Long code, List<Long> statusCodes) {
        for (Long statusCode : statusCodes) {
            abnormalTypeRepository.bindAlarmStatus(code, statusCode);
        }
    }
}
